// 2013-7-28上午11:56:41  net.betou.trade.main.manager.impl.IntermediateProvidersMngImpl.java

package net.betou.trade.main.manager.impl;

import java.util.Date;
import java.util.Set;

import net.betou.common.hibernate3.Updater;
import net.betou.common.page.Pagination;
import net.betou.common.security.encoder.PwdEncoder;
import net.betou.common.security.encoder.SaltGenerator;
import net.betou.common.security.exception.BadCredentialsException;
import net.betou.common.security.exception.UsernameNotFoundException;
import net.betou.trade.entity.main.AgentAndAdmins;
import net.betou.trade.entity.main.AgentAndAdminsExt;
import net.betou.trade.entity.main.Role;
import net.betou.trade.main.dao.AgentAndAdminsDao;
import net.betou.trade.main.dao.RoleDao;
import net.betou.trade.main.manager.AgentAndAdminsExtMng;
import net.betou.trade.main.manager.AgentAndAdminsMng;
import net.betou.trade.main.manager.RoleMng;
import net.betou.trade.role.setting.AgentAdminFinderConfig;
import net.betou.trade.role.setting.AgentFinderConfig;
import net.betou.trade.role.setting.ProxyFinderConfig;
import net.betou.trade.web.DBConstants;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * @deprecated
 * 居间、系统管理员、居间管理员Service
 * 
 * @author 叶装装
 */
@Service
@Transactional
public class AgentAndAdminsMngImpl implements AgentAndAdminsMng{

	public AgentAndAdmins updateAgency( Boolean disabled, String password, String email, String mobile, String intermediaName, AgentAndAdmins bean, AgentAndAdminsExt ext, Integer [ ] roleIds ) {

		if( StringUtils.isNotBlank( password ) ){
			String loginSalt = salt.randomSalt( ); // 重新生成密码混淆

			bean.setSalt( loginSalt );
			bean.setPassword( pwdEncoder.encodePassword( password, loginSalt ) );
		}

		if( disabled == null ){
			bean.setDisabled( true );
		}else{
			bean.setDisabled( false );
		}

		bean.setEmail( StringUtils.isBlank( email ) ? null : email );
		bean.setMobile( StringUtils.isBlank( mobile ) ? null : mobile );
		bean.setIntermediaName( intermediaName );

		bean.getRoles( ).clear( ); // 清空角色

		boolean updateAgency = true; // 是否更新角色为

		if( roleIds != null ){
			for ( Integer id : roleIds ){
				Role role = roleMng.findById( id );
				bean.addToRoles( role );

				// 如果选择的角色中，没有以j开始的角色，就
				if( "j".equals( role.getIdentity( ) ) ){
					updateAgency = true;
				}else{
					updateAgency = false;
				}
			}
		}

		bean.setAgencyOrProxy( updateAgency );

		Updater< AgentAndAdmins > updater = new Updater< AgentAndAdmins >( bean );
		updater.include( "email" );
		updater.include( "mobile" );
		updater.include( "agencyOrProxy" );

		bean = dao.updateByUpdater( updater ); // 更新主表
		extMng.update( ext, bean ); // 更新附表

		return bean;

	}

	@Transactional( readOnly = true )
	public AgentAndAdmins findAgentAdmin( Integer id ) {
		return dao.findAgentOrAdmins( false, true, id );
	}

	@Transactional( readOnly = true )
	public AgentAndAdmins findAgent( Integer id ) {
		return dao.findAgentOrAdmins( false, false, id );
	}

	@Transactional( readOnly = true )
	public AgentAndAdmins findAdmin( Integer id ) {
		return dao.findAgentOrAdmins( true, true, id );
	}

	public AgentAndAdmins saveProxy( AgentAndAdmins currentAdmin, String ip, AgentAndAdmins bean, AgentAndAdminsExt ext ) {
		return save( currentAdmin, ip, bean, ext, false );
	}

	public AgentAndAdmins saveAgency( AgentAndAdmins currentAdmin, String ip, AgentAndAdmins bean, AgentAndAdminsExt ext ) {
		return save( currentAdmin, ip, bean, ext, true );
	}

	private AgentAndAdmins save( AgentAndAdmins currentAdmin, String ip, AgentAndAdmins bean, AgentAndAdminsExt ext, boolean agency ) {
		bean.setCreateIp( ip );

		String loginSalt = salt.randomSalt( );

		bean.setSalt( loginSalt );
		bean.setPassword( pwdEncoder.encodePassword( bean.getPassword( ), loginSalt ) );

		Role role;
		
		if( agency ){
			
			if( currentAdmin.getDeep( ) == 0 ){
				role = roleMng.findAgency( );
			}else{
				role = roleMng.findMyAgency( currentAdmin.getId( ) );
			}
			
			bean.addToRoles( role ); // 设置机构角色
			bean.saveToAgency( currentAdmin );

		}else{
			bean.addToRoles( roleMng.findMyProxy( currentAdmin.getId( ) ) ); // 设置代理商角色
			bean.saveToProxy( currentAdmin );
		}

		dao.save( bean );
		extMng.save( ext, bean );
		
		afterSaveAgency( agency, currentAdmin, bean );

		return bean;
	}

	/**
	 * @deprecated
	 */
	public AgentAndAdmins saveAgent( boolean agency, AgentAndAdmins currentAdmin, String ip, AgentAndAdmins bean, AgentAndAdminsExt ext ) {

		bean.setCreateIp( ip );

		String loginSalt = salt.randomSalt( );

		bean.setSalt( loginSalt );
		bean.setPassword( pwdEncoder.encodePassword( bean.getPassword( ), loginSalt ) );

		if( agency ){
			bean.addToRoles( roleMng.findAgency( ) ); // 设置机构角色
			bean.initToSaveAgent( );

		}else{
			bean.addToRoles( roleMng.findProxy( ) );
			bean.initToSaveAgent( currentAdmin );
		}

		dao.save( bean );
		extMng.save( ext, bean );

		return bean;

	}

	public AgentAndAdmins updateAgentAdmin( Boolean disabled, String password, String email, String mobile, AgentAndAdmins bean, AgentAndAdminsExt ext, Integer [ ] roleIds ) {

		if( StringUtils.isNotBlank( password ) ){
			String loginSalt = salt.randomSalt( ); // 重新生成密码混淆

			bean.setSalt( loginSalt );
			bean.setPassword( pwdEncoder.encodePassword( password, loginSalt ) );
		}

		if( disabled == null ){
			bean.setDisabled( true );
		}else{
			bean.setDisabled( false );
		}

		bean.setEmail( StringUtils.isBlank( email ) ? null : email ); // 设置成null
		bean.setMobile( StringUtils.isBlank( mobile ) ? null : mobile );
		if( roleIds != null ){
			bean.getRoles( ).clear( ); // 清空角色
			for ( Integer id : roleIds ){
				bean.addToRoles( roleMng.findById( id ) );
			}
		}

		Updater< AgentAndAdmins > updater = new Updater< AgentAndAdmins >( bean );
		updater.include( "email" );
		updater.include( "mobile" );
		bean = dao.updateByUpdater( updater ); // 更新主表
		extMng.update( ext, bean ); // 更新附表

		return bean;
	}

	public AgentAndAdmins updateAdmin( Boolean disabled, String password, String email, AgentAndAdmins bean, AgentAndAdminsExt ext, Integer [ ] roleIds ) {

		if( StringUtils.isNotBlank( password ) ){
			String loginSalt = salt.randomSalt( ); // 重新生成密码混淆

			bean.setSalt( loginSalt );
			bean.setPassword( pwdEncoder.encodePassword( password, loginSalt ) );
		}

		if( disabled == null ){
			bean.setDisabled( true );
		}else{
			bean.setDisabled( false );
		}

		bean.setEmail( StringUtils.isBlank( email ) ? null : email ); // 设置成null

		bean.getRoles( ).clear( ); // 清空角色

		if( roleIds != null ){
			for ( Integer id : roleIds ){
				bean.addToRoles( roleMng.findById( id ) );
			}
		}

		Updater< AgentAndAdmins > updater = new Updater< AgentAndAdmins >( bean );
		updater.include( "email" );
		bean = dao.updateByUpdater( updater ); // 更新主表
		extMng.update( ext, bean ); // 更新附表

		return bean;
	}

	public AgentAndAdmins saveAgentAdmin( AgentAndAdmins currentAdmin, String ip, Integer [ ] roleIds, AgentAndAdmins bean, AgentAndAdminsExt ext ) {
		bean.setCreateIp( ip );
		String loginSalt = salt.randomSalt( );

		bean.setSalt( loginSalt );
		bean.setPassword( pwdEncoder.encodePassword( bean.getPassword( ), loginSalt ) );

		if( roleIds != null ){
			for ( Integer id : roleIds ){
				bean.addToRoles( roleMng.findById( id ) );
			}
		}

		bean.saveToAdmin( currentAdmin );

		dao.save( bean );
		extMng.save( ext, bean );

		return bean;
	}

	public AgentAndAdmins saveAdmin( String ip, Integer [ ] roleIds, AgentAndAdmins bean, AgentAndAdminsExt ext ) {

		bean.setCreateIp( ip );
		String loginSalt = salt.randomSalt( );

		bean.setSalt( loginSalt );
		bean.setPassword( pwdEncoder.encodePassword( bean.getPassword( ), loginSalt ) );

		if( roleIds != null ){
			for ( Integer id : roleIds ){
				bean.addToRoles( roleMng.findById( id ) );
			}
		}

		bean.initToSaveAdmin( );

		dao.save( bean );
		extMng.save( ext, bean );

		return bean;

	}

	public AgentAndAdmins deleteById( Integer id ) {
		return dao.deleteById( id );
	}

	public AgentAndAdmins [ ] deleteByIds( Integer [ ] ids ) {
		AgentAndAdmins [ ] beans = new AgentAndAdmins [ ids.length ];
		for ( int i = 0; i < ids.length; i++ ){
			beans[ i ] = dao.deleteById( ids[ i ] );
		}
		return beans;
	}

	public AgentAndAdmins login( String username, String password, String ip ) throws UsernameNotFoundException, BadCredentialsException {
		AgentAndAdmins user = findByUsername( username );

		if( user == null ){
			throw new UsernameNotFoundException( "username not found: " + username );
		}

		if( !pwdEncoder.isPasswordValid( user.getPassword( ), password, user.getSalt( ) ) ){
			throw new BadCredentialsException( "password invalid" );
		}
		// 如果没被禁用，才更新登录次数
		if( !user.getDisabled( ) ){
			// 要存放上次登录的IP. 然后再更新, 所以还需要两个字段，保存上次登录信息的
			updateLoginInfo( user.getId( ), ip );
		}

		return user;
	}

	public void updateLoginInfo( Integer userId, String ip ) {

		AgentAndAdmins user = findById( userId );
		if( user != null ){
			user.setLoginCount( user.getLoginCount( ) + 1 );
			user.setLoginIp( ip );
			user.setLoginDate( new Date( ) );
		}

	}

	@Transactional( readOnly = true )
	public boolean emailNotExist( String email ) {
		return dao.countByEmail( email ) <= 0;
	}

	@Transactional( readOnly = true )
	public AgentAndAdmins findById( Integer id ) {
		return dao.findById( id );
	}

	@Transactional( readOnly = true )
	public AgentAndAdmins findMyAgent( Integer id, Integer selfId, Boolean system ) {
		if( system ){
			return this.findAgent( id );
		}
		return dao.findMyData( id, selfId, false );
	}

	@Transactional( readOnly = true )
	public AgentAndAdmins findMyAgentAdmin( Integer id, Integer selfId, Boolean system ) {
		if( system ){
			return this.findAgentAdmin( id );
		}
		return dao.findMyData( id, selfId, true );
	}

	@Transactional( readOnly = true )
	public AgentAndAdmins findByUsername( String username ) {
		return dao.findByUsername( username );
	}

	@Transactional( readOnly = true )
	public boolean mobileNotExist( String mobile ) {
		return dao.countByMobile( mobile ) <= 0;
	}

	@Transactional( readOnly = true )
	public boolean nameNotExist( String name ) {
		return dao.countByName( name ) <= 0;
	}

	@Transactional( readOnly = true )
	public boolean userNameNotExist( String username ) {
		return dao.countByUsername( username ) <= 0;
	}

	@Transactional( readOnly = true )
	public Pagination getAdminPage( String searchProperty, String searchValue, String orderProperty, String orderDirection, int pageNo, int pageSize, String filterStatus ) {
		return dao.getPage( true, null, null, null, searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, filterStatus ); // 系统管理员，只需要直接传入System
	}

	@Transactional( readOnly = true )
	public Pagination getAgentAdminPage( AgentAndAdmins admin, String searchProperty, String searchValue, String orderProperty, String orderDirection, int pageNo, int pageSize, String filterStatus ) {
		Pagination pagination;
		if( admin.getSystem( ) ){
			pagination = dao.getPage( false, true, null, null, searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, filterStatus );
		}else{

			AgentAdminFinderConfig config = new AgentAdminFinderConfig( admin );

			if( config.isSelf( ) ){
				pagination = dao.getPage( false, true, null, admin.getId( ), searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, filterStatus );
			}else{
				pagination = dao.getPageByCriteria( searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, config.getDeepSQL( ) );
			}
		}

		return pagination;
	}

	@Transactional( readOnly = true )
	public Pagination getProxyPage( AgentAndAdmins user, String searchProperty, String searchValue, String orderProperty, String orderDirection, int pageNo, int pageSize, String filterStatus ) {

		Pagination pagination;
		if( user.getSystem( ) ){ // 系统管理员，直接获取数据
			pagination = dao.getPage( false, false, false, null, searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, filterStatus );
		}else{

			ProxyFinderConfig config = new ProxyFinderConfig( user );
			if( config.isSelf( ) ){ // 查询自己的
				pagination = dao.getPage( false, false, false, user.getId( ), searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, filterStatus );
			}else{ // 深度查询
				pagination = dao.getPageByCriteria( searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, config.getDeepSQL( ) );
			}
		}

		return pagination;

	}

	@Transactional( readOnly = true )
	public Pagination getAgentPage( AgentAndAdmins user, String searchProperty, String searchValue, String orderProperty, String orderDirection, int pageNo, int pageSize, String filterStatus ) {
		Pagination pagination;
		if( user.getSystem( ) ){ // 系统管理员，直接获取数据
			pagination = dao.getPage( false, false, true, null, searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, filterStatus );
		}else{

			AgentFinderConfig config = new AgentFinderConfig( user );
			if( config.isSelf( ) ){ // 查询自己的
				pagination = dao.getPage( false, false, true, user.getId( ), searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, filterStatus );
			}else{ // 深度查询
				pagination = dao.getPageByCriteria( searchProperty, searchValue, orderProperty, orderDirection, pageNo, pageSize, config.getDeepSQL( ) );
			}
		}

		return pagination;
	}

	private void afterSaveAgency( boolean agency, AgentAndAdmins currentAdmin, AgentAndAdmins bean ) {

		if( !agency || currentAdmin.getDeep( ) != 0 ){
			return;
		}

		Role agencyRole = roleMng.findAgency( );
		Role proxyRole = roleMng.findProxy( );

		Set< String > agencyPerms = agencyRole.getPerms( );
		Set< String > proxyPerms = proxyRole.getPerms( );

		Role newAgency = new Role( );
		newAgency.initToDefault( DBConstants.DEFINED_AGENCY_IDENTITY, "机构", bean, 0, agencyPerms );
		Role newProxy = new Role( );
		newProxy.initToDefault( DBConstants.DEFINED_PROXY_IDENTITY, "代理商", bean, 1, proxyPerms );

		roleDao.save( newAgency );
		roleDao.save( newProxy );
		
		bean.getRoles( ).clear( );
		
		bean.addToRoles( newAgency ); // 更新角色

	}

	@Autowired
	private AgentAndAdminsDao dao;

	@Autowired
	private PwdEncoder pwdEncoder;

	@Autowired
	private RoleMng roleMng;

	@Autowired
	private AgentAndAdminsExtMng extMng;

	@Autowired
	private SaltGenerator salt;

	@Autowired
	private RoleDao roleDao;

}
